package com.zmn.brs.business.impl.dingtalk;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.openservices.shade.com.alibaba.rocketmq.common.message.MessageClientIDSetter;
import com.zmn.brs.business.interfaces.dingtalk.DingTalkBService;
import com.zmn.brs.common.constant.BrsMqConst;
import com.zmn.brs.common.constant.RedisKeyConst;
import com.zmn.brs.common.model.mq.sms.DingTalkParams;
import com.zmn.brs.common.model.mq.sms.SendParams;
import com.zmn.brs.dubbo.constant.DubboConsts;
import com.zmn.brs.model.entity.robot.DingGroupRobot;
import com.zmn.brs.services.interfaces.robot.DingGroupRobotService;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.manager.mq.interfaces.ZmnMQSender;
import com.zmn.mcc.common.dto.dingtalk.RobotSendGroupMessage;
import com.zmn.mcc.common.dto.staff.StaffIdAndDTalkIdDRO;
import com.zmn.mcc.dubbo.interfaces.staff.StaffListRemoteService;
import com.zmn.mcc.dubbo.interfaces.staff.dingtalk.DingTalkRemoteService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.support.atomic.RedisAtomicInteger;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * 描述： 钉钉消息推送实现
 *
 * @author chongw
 * @since 2021-06-28 9:55
 */
@Slf4j
@Service
public class DingTalkBServiceImpl implements DingTalkBService {

    final static String TAG = "钉钉消息推送实现";

    @Reference(version = com.zmn.mcc.dubbo.dto.DubboConsts.INTERFACE_VERSION, check = false)
    DingTalkRemoteService dingTalkRemoteService;

    @Reference(version = DubboConsts.INTERFACE_VERSION, check = false)
    private StaffListRemoteService staffListRemoteService;

    @Resource
    private DingGroupRobotService robotService;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private ZmnMQSender zmnMqSender;

    /**
     * 发送钉钉群消息， 默认缓存3天
     * @param robotId
     * @param redisKey
     * @param content
     */
    @Override
    public void sendDingtalkGroup(Integer robotId, String redisKey, String content){
        this.sendDingtalkGroup(robotId, redisKey , 3L, TimeUnit.DAYS, content);
    }

    /**
     * 发送钉钉群消息
     * @param robotId
     * @param content
     */
    @Override
    public void sendDingtalkGroup(Integer robotId, String content){
        this.sendDingtalkGroup(robotId , null , content);
    }

    /**
     * 发送钉钉群消息，设置有效时间
     * @param robotId
     * @param redisKey
     * @param expireTime
     * @param unit
     * @param content
     */
    @Override
    public void sendDingtalkGroup(Integer robotId, String redisKey, Long expireTime, TimeUnit unit, String content){
        if(NumberUtil.isNullOrZero(robotId)){
            log.error("[{}]，机器人ID不能为空", TAG);
            return;
        }
        //获取钉钉群配置
        DingGroupRobot dingGroupRobot = Optional.ofNullable(robotService.findById(robotId)).orElse(DingGroupRobot.builder().build());
        if(StringUtil.isBlank(dingGroupRobot.getAccessToken()) || StringUtil.isBlank(dingGroupRobot.getSecret())){
            log.error("[{}]，机器人配置accessToken或scret不能为空", TAG);
            return;
        }
        RobotSendGroupMessage message = RobotSendGroupMessage.builder()
                .accessToken(dingGroupRobot.getAccessToken())
                .secret(dingGroupRobot.getSecret())
                .content(content)
                .build();
        try {
            long sendMessageToGroupByRobotTimeStart = System.currentTimeMillis();
            ResponseDTO<Boolean> sendResponse = dingTalkRemoteService.sendMessageToGroupByRobot(message);
            log.info("[{}]，[耗时：{}]，事件触发，发送钉钉群消息", TAG, System.currentTimeMillis() - sendMessageToGroupByRobotTimeStart);
            if (sendResponse.getData() && StringUtil.isNotBlank(redisKey)) {
                //数据自增
                RedisAtomicInteger dingtalkCounter = new RedisAtomicInteger(redisKey, redisTemplate.getConnectionFactory());
                //设置数据有效期
                dingtalkCounter.expire(expireTime, unit);
                //获取当天统计数量
                dingtalkCounter.incrementAndGet();
                return ;
            }
            log.info("[{}]，事件触发，发送消息到钉钉群失败, 文本信息：{}", TAG, sendResponse.getMessage());
        } catch (Exception e) {
            log.error("[{}]，事件触发，发送消息到钉钉群异常, error：{}", TAG, e.getMessage());
        }
    }


    /**
     * 推送钉钉消息
     * @param staffId 员工ID
     * @param object
     */
    @Override
    public void sendDingTalk(Integer staffId, JSONObject object, Integer smsRuleId, String pushTopic) {
        if (staffId == null) {
            return;
        }
        ResponseDTO<List<StaffIdAndDTalkIdDRO>> resultStaffIdAndTalkIdList = staffListRemoteService.listStaffIdAndDTalkIdByStaffIdList(Collections.singletonList(staffId));
        if (!resultStaffIdAndTalkIdList.isSuccess()) {
            log.error("[{}]，查询dingTalkId失败, staffId:{}", TAG, staffId);
            return ;
        }
        List<StaffIdAndDTalkIdDRO> staffIdAndDingTalkIdList =  Optional.ofNullable( resultStaffIdAndTalkIdList.getData()).orElse(new ArrayList<>());
        if (staffIdAndDingTalkIdList == null || staffIdAndDingTalkIdList.size() ==0) {
            log.error("[{}]，查询dingTalkId失败, staffId:{}", TAG, staffId);
            return;
        }
        StaffIdAndDTalkIdDRO staffIdAndDingTalkId = staffIdAndDingTalkIdList.get(0);
        if (staffIdAndDingTalkId == null) {
            log.error("[{}]，查询dingTalkId失败, staffId:{}", TAG, staffId);
            return;
        }
        if(StringUtil.isBlank(staffIdAndDingTalkId.getDTalkId())){
            log.error("[{}]，未查询到该用户钉钉账号Id, staffId:{}", TAG, staffId);
            return;
        }
        sendDingTalk(staffIdAndDingTalkId.getDTalkId(), object.toJSONString() , smsRuleId,pushTopic);
    }

    /**
     * 发送钉钉消息
     * @param dingTalkId 钉钉id
     * @param text 文本
     */
    @Override
    public void sendDingTalk(String dingTalkId, String text, Integer smsRuleId, String pushTopic) {
        try {
            JSONObject data = JSONObject.parseObject(text);
            data.put("timeStamp" , System.currentTimeMillis());
            String msg = data.toJSONString();
            log.info("[{}], 发送钉钉消息,dingTalkId:{}, text:{}", TAG, dingTalkId, msg);
            if (StringUtil.isNotBlank(msg)) {
                String serialNumber = MessageClientIDSetter.createUniqID();
                SendParams sendParams = SendParams.builder()
                        .ruleId(smsRuleId)
                        .callsName("brs")
                        .areaId(null)
                        .channelId(null)
                        .serialNumber(serialNumber)
                        .build();
                DingTalkParams dingTalkParams = DingTalkParams.builder()
                        .dingTalkId(dingTalkId)
                        .imageUrl(null)
                        .params(msg)
                        .build();
                sendParams.setDingTalkParams(dingTalkParams);
                zmnMqSender.send(pushTopic, BrsMqConst.MESSAGE_CENTER_SYSTEM, serialNumber, JSON.toJSONString(sendParams));
                log.info("[{}]，topic:{}，tags：{}，dingTalkId：{}，推送场景ID：{}，serialNumber：{}，发送文本消息到信息中心系统成功。推送内容：{}", TAG, pushTopic, BrsMqConst.MESSAGE_CENTER_SYSTEM, dingTalkId, smsRuleId, serialNumber, JSON.toJSONString(sendParams));
            }
        }catch (Exception e){
            log.error("[{}]，dingTalkId：{}，场景ID：{}，发送文本消息到信息中心系统异常。异常信息：{}", TAG, dingTalkId, smsRuleId, e);
        }
    }
}
